<?php
declare(strict_types=1);


use SixShop\Payment\Enum\NumberBizEnum;

if (!function_exists('generate_number')) {
    /**
     * 生成20位数字编号
     *
     * 如果位数不够时可以调整$randomLength值，默认为3位
     *
     * 格式：14位日期时间(YmdHis) + 2位业务码(00-99) + 3位随机数 + 1位校验位
     *
     * @param NumberBizEnum $bizCode 业务编码(0-99)，1 订单号 2 订单支付
     * @return string 20位数字编号
     * @throws InvalidArgumentException 当业务码不在0-99范围时抛出
     */
    function generate_number(NumberBizEnum $bizCode, int $randomLength = 3): string
    {
        $bizCode = $bizCode->value;
        // 1. 校验业务码范围
        if ($bizCode < 0 || $bizCode > 99) {
            throw new InvalidArgumentException('业务码必须是0-99之间的整数');
        }
        // 2. 14位日期时间（年月日时分秒）
        $datetime = date('YmdHis');
        // 3. 2位业务码（自动补零）
        $bizPart = str_pad((string)$bizCode, 2, '0', STR_PAD_LEFT);
        // 4. 3位安全随机数
        $random = str_pad((string)random_int(0, 999), $randomLength, '0', STR_PAD_LEFT);
        // 5. 组合前19位
        $prefix = $datetime . $bizPart . $random;
        // 6. 计算校验位（简单加权求和）
        $sum = 0;
        for ($i = 0; $i < 19; $i++) {
            $sum += $prefix[$i] * (($i % 2) ? 3 : 1);
        }
        $checkDigit = (10 - ($sum % 10)) % 10;

        return $prefix . $checkDigit;
    }
}

if (!function_exists('validate_order_number')) {
    /**
     * 验证订单号有效性
     */
    function validate_order_number(string $orderNo): bool
    {
        // 基础格式检查
        if (!preg_match('/^\d{20}$/', $orderNo)) {
            return false;
        }

        // 校验位验证
        $prefix = substr($orderNo, 0, 19);
        $check = substr($orderNo, -1);

        $sum = 0;
        for ($i = 0; $i < 19; $i++) {
            $sum += $prefix[$i] * (($i % 2) ? 3 : 1);
        }
        return ((10 - ($sum % 10)) % 10) == $check;
    }
}